package com.sxj.springsourcecode.springframework.factory.support;

import com.sxj.springsourcecode.springframework.factory.config.BeanDefinition;
import com.sxj.springsourcecode.springframework.factory.config.BeanDefinitionRegistry;
import com.sxj.springsourcecode.springframework.factory.config.BeanPostProcessor;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @ProjectName: spring-source-code
 * @Package: com.sxj.springsourcecode.springframework.factory.support
 * @ClassName: DefaultListableBeanFactory
 * @Author: sxj
 * @Description:
 * @Date: 2024/2/21 11:42
 * @Version: 1.0.0
 */
public abstract class ConfigurableListableBeanFactory extends AbstractAutowireBeanFactory implements BeanDefinitionRegistry {
    private List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
    private List<DisposableBeanAdapter> disposableBeanAdapters = new CopyOnWriteArrayList<>();

    private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    
    @Override
    public void addBeanPostProcessor(BeanPostProcessor processor) {
        beanPostProcessors.add(processor);
    }

    /**
     * TODO 
     * 
     */
    public Map<String, BeanDefinition> getBeanDefinitionMap(){
        return beanDefinitionMap;
    }
    
    /**
     * TODO 
     * 
     */
    public abstract void preInstantiateSingletons();

    @Override
    public List<BeanPostProcessor> getBeanPostProcessors() {
        return beanPostProcessors;
    }



    @Override
    public void registerDispoableBean(String beanName, Object bean, BeanDefinition beanDefinition) {
        DisposableBeanAdapter adapter = new DisposableBeanAdapter(beanName, bean, beanDefinition);
        disposableBeanAdapters.add(adapter);
    }

    public List<DisposableBeanAdapter> getDisposableBeanAdapters() {
        return disposableBeanAdapters;
    }

    public void destorySingletons() {
        List<DisposableBeanAdapter> adapters = getDisposableBeanAdapters();
        for (DisposableBeanAdapter adapter : adapters) {
            adapter.destroy();
        }
    }

    @Override
    public void registerBeanDefiniton(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName,beanDefinition);
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) {
        return beanDefinitionMap.get(beanName);
    }
}
